package vip.xiaonuo.smzq.modular.lifecycle.service.module.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.math.MathUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.stereotype.Service;


import vip.xiaonuo.smzq.modular.lifecycle.base.KqfwCoordinates;
import vip.xiaonuo.smzq.modular.lifecycle.constant.LifeCycleConstant;
import vip.xiaonuo.smzq.modular.lifecycle.service.module.CommonService;
import vip.xiaonuo.smzq.modular.lifecycle.util.CoordinateTranUtil;
import vip.xiaonuo.smzq.modular.lifecycle.util.HutoolExtend;
import vip.xiaonuo.smzq.modular.lifecycle.vo.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <ul>
 * <li>name:  LifeCycleServiceImpl</li>
 * <li>author name: GEOSCENE_YUYANFEI</li>
 * <li>create time: 2024-03-20 15:31:25</li>
 * </ul>
 */
@Service
public class CommonServiceImpl implements CommonService {

    @Resource
    CoordinateTranUtil coordinateTranUtil;

    @Resource
    HutoolExtend hutoolExtend;

    /**
     * 获取坐标字符串
     *
     * @param kqfwCoordinatesList
     * @return
     */
    @Override
    public String getCoordinatesStr(List<KqfwCoordinates> kqfwCoordinatesList) {
        String result = "";
        String coordinatesStr = "";
        try {
            //获取图形数量
            Integer graphicCount = 0;
            //获取拐点个数
            int point = 0;
            //每个图形的所有信息字符串
            String point2000 = "";
            List<String> fwList = CollUtil.newArrayList();
            for (int i = 0; i < kqfwCoordinatesList.size(); i++) {
                KqfwCoordinates kqfwCoordinates = kqfwCoordinatesList.get(i);
                if (!kqfwCoordinates.getInflectionPoint().equals("*")) {
                    if (point2000.equals("")) {
                        point2000 = kqfwCoordinates.getInflectionPoint() + "," + kqfwCoordinates.getX() + "," + kqfwCoordinates.getY();
                    } else {
                        point2000 = point2000 + "," + kqfwCoordinates.getInflectionPoint() + "," + kqfwCoordinates.getX() + "," + kqfwCoordinates.getY();
                    }
                    point++;
                } else {
                    coordinatesStr = point + "," + point2000 + "," + kqfwCoordinates.getX() + "," + kqfwCoordinates.getY() + "," +
                            kqfwCoordinates.getOreBodyIdentification() + "," + kqfwCoordinates.getNature();
                    fwList.add(coordinatesStr);
                    graphicCount++;
                    point = 0;
                    point2000 = "";
                }

            }
            result = graphicCount + "," + CollUtil.join(fwList,",");
        } catch (Exception e) {

        }
        return result;
    }



    /*public String getCoordinatesStr(List<KqfwCoordinates> kqfwCoordinatesList) {
        String coordinatesStr = "";
        try {
            //获取图形数量
            Integer graphicCount = 0;
            //获取拐点个数
            int point = 0;
            //每个图形的所有信息字符串
            String point2000 = "";
            for (int i = 0; i < kqfwCoordinatesList.size(); i++) {
                KqfwCoordinates kqfwCoordinates = kqfwCoordinatesList.get(i);
                if (!kqfwCoordinates.getInflectionPoint().equals("*")) {
                    if (point2000.equals("")) {
                        point2000 = kqfwCoordinates.getInflectionPoint() + "," + kqfwCoordinates.getX() + "," + kqfwCoordinates.getY();
                    } else {
                        point2000 = point2000 + "," + kqfwCoordinates.getInflectionPoint() + "," + kqfwCoordinates.getX() + "," + kqfwCoordinates.getY();
                    }
                    point++;
                } else {
                    coordinatesStr = point + "," + point2000 + "," + kqfwCoordinates.getX() + "," + kqfwCoordinates.getY() + "," +
                            kqfwCoordinates.getOreBodyIdentification() + "," + kqfwCoordinates.getNature();
                    graphicCount++;
                    point = 0;
                    point2000 = "";
                }

            }
            coordinatesStr = graphicCount + "," + coordinatesStr;
        } catch (Exception e) {

        }
        return coordinatesStr;
    }*/



    /**
     * 根据坐标字符串返回拐点坐标对象集合
     *
     * @param coordinatesStr 坐标字符串
     *                       <p>
     *                       2,
     *                       5,
     *                       1,4421028.05,39571109.36,-----4
     *                       2,4421062.05,39571064.36,
     *                       3,4421110.05,39571178.36,
     *                       4,4421088.05,39571236.36,
     *                       5,4421024.05,39571217.36,
     *                       103,47,,1,
     *                       3,
     *                       6,4420876.05,39571372.36,
     *                       7,4420967.05,39571412.36,
     *                       8,4420819.05,39571421.36,
     *                       103,47,,1,
     * @return
     */
    @Override
    public  List<KqfwCoordinates> getKqfwCoordinates(String coordinatesStr) {
        List<KqfwCoordinates> kqfwCoordinatesList = new ArrayList<>();
        try{
            coordinatesStr=coordinatesStr.trim();
            //转换成数组
            String[] coordinatesArry = coordinatesStr.replaceAll(" ", "").split(",");
            //获取第一个元素判断是几个图形
            Integer graphicCount = Integer.parseInt(coordinatesArry[0]);
            //获取第一个图像的坐标个数
            Integer coordinatesCount = Integer.parseInt(coordinatesArry[1]);

            for (int i = 2; i < coordinatesArry.length; ) {

                KqfwCoordinates kqfwCoordinates = new KqfwCoordinates();
                if (coordinatesCount == 0) {
                    //x
                    kqfwCoordinates.setX(coordinatesArry[i]);
                    //Y
                    kqfwCoordinates.setY(coordinatesArry[i+1]);
                    //拐点
                    kqfwCoordinates.setInflectionPoint("*");
                    if (coordinatesArry[i + 2] != null) {
                        //矿体标识
                        kqfwCoordinates.setOreBodyIdentification(coordinatesArry[i + 3]);
                    }

                    if (coordinatesArry[i + 3] != null) {
                        //性质
                        kqfwCoordinates.setNature(coordinatesArry[i + 3]);
                    }
                    if ((i+4)<coordinatesArry.length){
                        if (coordinatesArry[i + 4] != null&&!coordinatesArry[i + 4].equals("")) {
                            // 获取图像的坐标个数
                            coordinatesCount = Integer.valueOf(coordinatesArry[i + 4]);
                        }
                    }
                    i = i + 5;
                } else {
                    //拐点
                    kqfwCoordinates.setInflectionPoint(coordinatesArry[i]);
                    if (coordinatesArry[i + 1] != null) {
                        //x
                        kqfwCoordinates.setX(coordinatesArry[i + 1]);
                    }
                    if (coordinatesArry[i + 2] != null&&!coordinatesArry[i + 2].equals("")) {
                        //Y
                        kqfwCoordinates.setY(coordinatesArry[i + 2]);
                    }
                    coordinatesCount--;
                    i = i + 3;
                }

                kqfwCoordinatesList.add(kqfwCoordinates);

            }
        }catch (Exception e){
            e.printStackTrace();
        }
        for (KqfwCoordinates kqfwCoordinates:kqfwCoordinatesList) {
            kqfwCoordinates.initCoor84(coordinateTranUtil.getAnalysisType(coordinatesStr),coordinateTranUtil );
        }
        return kqfwCoordinatesList;
    }

    @Override
    public List<List<Double>> getMutiPointXY(String coordinatesStr) {
        List<List<Double>> result = CollUtil.newArrayList();
        String repCoorStr = getMutiPointStr(coordinatesStr);
        if(!StrUtil.contains(repCoorStr,"EMPTY")){
            List<String> spStrs = StrUtil.split(repCoorStr,",");
            for (String spStr:spStrs) {
                List<Double> xyList = Convert.toList(Double.class,StrUtil.split(spStr," "));
                result.add(xyList);
            }
        }

        return result;
    }

    @Override
    public String getMutiPointStr(String coordinatesStr) {
        coordinatesStr = StrUtil.replace(coordinatesStr,"MULTIPOLYGON","");
        coordinatesStr = StrUtil.replace(coordinatesStr,"(","");
        coordinatesStr = StrUtil.replace(coordinatesStr,")","");
        return coordinatesStr;

    }

    @Override
    public Dict getMaxMinGroundHeight(String coorStr) {
        Dict result = Dict.create();
        List<KqfwCoordinates> coors = this.getKqfwCoordinates(coorStr);
        if(CollUtil.size(coors)>0){
            List<KqfwCoordinates> heightCoors = coors.stream().filter(ele->StrUtil.equals("*",ele.getInflectionPoint())).collect(Collectors.toList());
            if(CollUtil.size(heightCoors)>0){
                KqfwCoordinates heightCoor = CollUtil.getFirst(heightCoors);

                if(ObjectUtil.isNotEmpty(heightCoor.getX())){
                    result.set(LifeCycleConstant.heightMaxKey,heightCoor.getX());
                }
                if(ObjectUtil.isNotEmpty(heightCoor.getY())){
                    result.set(LifeCycleConstant.heightMinKey,heightCoor.getY());
                }

            }
        }
        return result;
    }

    @Override
    public List<ThreeDHeightVO> getThreeDHeightVOS(String coorStr) {
        List<ThreeDHeightVO> result = CollUtil.newArrayList();
//        得到最大和最小高度
        Dict maxMinHeight = this.getMaxMinGroundHeight(coorStr);

        Double maxHeight = maxMinHeight.getDouble(LifeCycleConstant.heightMaxKey);
        Double minHeight = maxMinHeight.getDouble(LifeCycleConstant.heightMinKey);
//        分四种情况，都有值，都没值，最大有最小没有，最小有，最大没有
//        都有值
        if(ObjectUtil.isNotEmpty(maxHeight) && ObjectUtil.isNotEmpty(minHeight)){
//           最大有最小没有
//            地上地下都有
            if(maxHeight>0 && minHeight<0){
                result.add(getThreeDHeightVO(maxHeight,maxHeight));
                result.add(getThreeDHeightVO(minHeight,Math.abs(minHeight)));
//                都是在地上
            }else if(maxHeight>0 && minHeight>0){
                result.add(getThreeDHeightVO(maxHeight,Math.abs(maxHeight - minHeight)));
//                只有地下
            }else if(maxHeight<0 && minHeight<0){
                result.add(getThreeDHeightVO(minHeight,Math.abs(maxHeight - minHeight)));
            }else if(maxHeight ==0 && minHeight<0){
                result.add(getThreeDHeightVO(minHeight,Math.abs(minHeight)));

            }else if(maxHeight>0 && minHeight==0){
                result.add(getThreeDHeightVO(maxHeight,maxHeight));
            }else if(maxHeight == 0 && minHeight==0){
                result.add(getThreeDHeightVO(1d,1d));
            }else if(maxHeight<0 && minHeight>0){
                result.add(getThreeDHeightVO(minHeight,minHeight));
                result.add(getThreeDHeightVO(maxHeight,Math.abs(maxHeight)));
            }
        }else if(ObjectUtil.isNotEmpty(maxHeight) && ObjectUtil.isEmpty(minHeight)){

            result.add(getThreeDHeightVO(maxHeight,Math.abs(maxHeight)));

//            最小有，最大没有
        }else if(ObjectUtil.isEmpty(maxHeight) && ObjectUtil.isNotEmpty(minHeight)){
            result.add(getThreeDHeightVO(minHeight,Math.abs(minHeight)));
        }
        return result;
    }

    @Override
    public List<ThreeWeftCoorVO> getThreeWeftCoorVOS(String coorStr){
        List<ThreeWeftCoorVO> result = CollUtil.newArrayList();

        List<List<KqfwCoordinates>> kcss = getKqfwCoorLs(coorStr);

        for (List<KqfwCoordinates> kcs:kcss) {
            ThreeWeftCoorVO threeWeftCoorVO = new ThreeWeftCoorVO();

            threeWeftCoorVO.initThreeDHVOS(kcs);

            String coorStrItem = this.getCoordinatesStr(kcs);
            PolygonWgs84V0 polygonWgs84V0 = coordinateTranUtil.coordinateDisposeWKT3(coorStrItem);
            threeWeftCoorVO.setCoor84(polygonWgs84V0.getMultiPolygon());

            result.add(threeWeftCoorVO);
        }

        return result;
    }

    @Override
    public boolean delFile(String filePath) {
        boolean result = true;
        if(FileUtil.exist(filePath) && FileUtil.isFile(filePath)){
            result =FileUtil.del(filePath);
        }
        return result;
    }

    @Override
    public List<List<KqfwCoordinates>> getKqfwCoorLs(String coorStr){
        List<List<KqfwCoordinates>> result = CollUtil.newArrayList();
//        得到范围坐标对象列表
        List<KqfwCoordinates> kqfwCoordinatesList = CollUtil.newArrayList();
        try{
            kqfwCoordinatesList = this.getKqfwCoordinates(coorStr);
        }catch (Exception e){
            e.printStackTrace();
        }

//        得到拐点为*的索引
        List<Integer> iss = CollUtil.newArrayList();
        for (int i = 0; i < CollUtil.size(kqfwCoordinatesList); i++) {
            KqfwCoordinates kfc = CollUtil.get(kqfwCoordinatesList,i);
            if(StrUtil.equals("*", kfc.getInflectionPoint())){
                iss.add(i);
            }
        }

        for (int i = 0; i < iss.size(); i++) {
            List<KqfwCoordinates> kfcs = CollUtil.newArrayList();
            Integer zI = CollUtil.get(iss,i);
            if(i==0){
                kfcs = CollUtil.sub(kqfwCoordinatesList, 0, zI+1);
                result.add(kfcs);
            }else{
                Integer start = CollUtil.get(iss,i-1);
                kfcs = CollUtil.sub(kqfwCoordinatesList,start+1,zI+1);
                result.add(kfcs);
            }
        }
        result = handerHoleCoorsItem(result);
        return result;
    }

    /*private List<List<KqfwCoordinates>> handerHoleCoors(List<List<KqfwCoordinates>> coorsList){
        for (int i = 0; i < CollUtil.size(coorsList); i++) {
            List<KqfwCoordinates> coors = CollUtil.get(coorsList,i);
            if(!checkHasHole(coors)){

            }

        }
    }*/

    /**
     * 检查是否是洞坐标
     * @param coors
     * @return
     */
    private boolean checkHasHole(List<KqfwCoordinates> coors){
        boolean result = false;
        for (KqfwCoordinates coor:coors) {
            if(StrUtil.equals("*",coor.getInflectionPoint()) && StrUtil.equals("-1",coor.getNature())){
                result = true;
                break;
            }
        }
        return result;
    }
    /**
     * 处理带洞的情况的列表
     * @param coorsList 坐标列表
     * @return
     */
    private List<List<KqfwCoordinates>> handerHoleCoorsItem(List<List<KqfwCoordinates>> coorsList){
        List<List<KqfwCoordinates>> result = CollUtil.newArrayList();
        List<Integer> iss = CollUtil.newArrayList();
//        one:
        for (int i = 0; i < CollUtil.size(coorsList); i++) {
            List<KqfwCoordinates> coors = CollUtil.get(coorsList,i);
//            two:
            /*for (KqfwCoordinates coor:coors) {
                if(StrUtil.equals("*",coor.getInflectionPoint()) && StrUtil.equals("-1",coor.getNature())){
                    isHole = true;
                    break two;
                }
            }*/
            boolean isHole = checkHasHole(coors);
            //            如果前一个是洞，则删除前一个的洞索引，将当前索引加入列表
            boolean preIsHole = false;
            if(i!=0){
                preIsHole = checkHasHole(CollUtil.get(coorsList,i-1));
            }

            if(isHole){
                if(!preIsHole){
                    iss.add(i);
                }else{
                    iss = hutoolExtend.listPop(iss,1);
                    iss.add(i);
                }

            }

        }


//        如果存在洞
        if(CollUtil.size(iss)!=0){
            for (int i = 0; i < CollUtil.size(iss); i++) {
                List<List<KqfwCoordinates>> kfcss = CollUtil.newArrayList();
                Integer zI = CollUtil.get(iss,i);
                if(i==0){
                    kfcss = CollUtil.sub(coorsList, 0, zI+1);
                    List<KqfwCoordinates> kfcs = CollUtil.newArrayList();
                    for (List<KqfwCoordinates> kfcssItem:kfcss) {
                        CollUtil.addAll(kfcs,kfcssItem);
                    }
                    List<List<KqfwCoordinates>> kfcsList = new ArrayList<>();
                    kfcsList.add(kfcs);
                    CollUtil.addAll(result,kfcsList);
                }else{
                    Integer start = CollUtil.get(iss,i-1);
                    kfcss = CollUtil.sub(coorsList,start+1,zI+1);
                    CollUtil.addAll(result,kfcss);
                }
            }
        }else{
            return coorsList;
        }

        return result;

    }

    @Override
    public boolean checkHasCoor(String coor) {
        return StrUtil.isNotBlank(coor) && !StrUtil.equals(coor,"0,");
    }

    /**
     * 得到3d高度信息
     * @param elevation 标高
     * @param graphHeight 图形高度
     * @return
     */
    private ThreeDHeightVO getThreeDHeightVO(Double elevation,Double graphHeight){
        ThreeDHeightVO result = new ThreeDHeightVO();
        result.setElevation(elevation);
        result.setGraphHeight(graphHeight);
        return result;
    }

}


